﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using ENT = CPPEI.ETL.Domain.Entities;

namespace CPPEI.ETL.Domain.Services
{
    public class DeleteService
    {

        /// <summary>
        /// 删除数据表
        /// </summary>
        /// <param name="tableId"></param>
        /// <returns></returns>
        public ServiceResult DeleteDataTable(string userId, Guid tableId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDtTable> dtRep = new EntityRepository<Entities.EDtTable>(dbContext);
                EntityRepository<Entities.EDtSourceMapping> dsmRep = new EntityRepository<Entities.EDtSourceMapping>(dbContext);

                Entities.EDtSourceMapping eDtSourceMapping = dsmRep.Get(p => p.DtTableId == tableId);
                if (eDtSourceMapping != null)
                {
                    return new ServiceResult(false, ErrorCode.DtTable_HasMapped, ErrorCode.String(ErrorCode.DtTable_HasMapped));
                }

                Entities.EDtTable eDtTable = dtRep.Get(p => p.Id == tableId);
                if (eDtTable == null)
                {
                    return new ServiceResult(false, ErrorCode.COM_OBJNotExist, ErrorCode.String(ErrorCode.COM_OBJNotExist));
                }

                new LogService().Write(DEF.LogLevel.Info, "ETL", string.Format("用户:{0}删除数据表:{1}", userId, tableId));
                return DeleteTable(dbContext, eDtTable);
            }
        }

        internal ServiceResult DeleteTable(EtlDbContext dbContext, Entities.EDtTable eDtTable)
        {
            EntityRepository<Entities.EDtTable> dtRep = new EntityRepository<Entities.EDtTable>(dbContext);
            dtRep.Delete(eDtTable);

            try
            {
                dbContext.Database.ExecuteSqlCommand("delete ETL_DtTableColumn where DtTableId={0}", eDtTable.Id);

                dbContext.SaveChanges();

                if (eDtTable.IsRawDt)
                {
                    // 删除数据表,只有为原始数据表的时候才删除
                    CPPEI.ETL.Domain.Util.DtTableUtil.DeleteRawDataTable(dbContext, eDtTable.ActualName, eDtTable.CacheName);
                }
                else
                {
                    if (eDtTable.CacheName != eDtTable.Name)
                    {
                        Logger.InfoToTag(Library.LogTAG, string.Format("{0}不是原始数据表,只删除缓存表:{1}", eDtTable.Name, eDtTable.CacheName));
                        // 删除数据表,只有为原始数据表的时候才删除
                        CPPEI.ETL.Domain.Util.DtTableUtil.DeleteRawDataTable(dbContext, null, eDtTable.CacheName);
                    }
                }

                return new ServiceResult(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError));
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag(Library.LogTAG, string.Format("删除数据表:{0},出错,ex:{1}", eDtTable.Id, ex));
                return new ServiceResult(false, ErrorCode.COM_Exception, ErrorCode.String(ErrorCode.COM_Exception));
            }
        }

        /// <summary>
        /// 删除数据源和数据表的映射关系
        /// </summary>
        /// <param name="dtSerId"></param>
        /// <param name="dtSourceId"></param>
        /// <param name="dtTableId"></param>
        /// <returns></returns>
        public ServiceResult DeleteDataTableMapping(string userId, Guid dtSerId, Guid dtSourceId, Guid dtTableId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.ETask> tRep = new EntityRepository<ENT.ETask>(dbContext);
                if (tRep.Count(p => p.DtSerId == dtSerId && p.DtSourceId == dtSourceId) > 0)
                {
                    return new ServiceResult(false, ErrorCode.DtSerHasTask, ErrorCode.String(ErrorCode.DtSerHasTask));
                }

                try
                {
                    dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceMapping where DtSerId={0} and DtSourceId={1} and DtTableId={2}", dtSerId, dtSourceId, dtTableId);
                    dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceColumnMapping where DtSerId={0} and DtSourceId={1} and DtTableId={2}", dtSerId, dtSourceId, dtTableId);
                    dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceDataIdentity where DtSerId={0} and DtSourceId={1}", dtSerId, dtSourceId);

                    new LogService().Write(DEF.LogLevel.Info, "ETL", string.Format("用户:{0}删除了数据表:{1}和数据源:{2}的映射关系.", userId, dtTableId, dtSourceId));

                    return new ServiceResult();
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag(Library.LogTAG, string.Format("delete Table Mapping for dtser:{0}, dtsource:{1}, dttable:{2}, ex:{3}",
                        dtSerId,
                        dtSourceId,
                        dtTableId,
                        ex));
                    return new ServiceResult(false, ErrorCode.COM_Exception, ErrorCode.String(ErrorCode.COM_Exception));
                }
            }
        }

        /// <summary>
        /// 删除数据表的映射关系，然后删除数据表
        /// </summary>
        /// <param name="dtSerId"></param>
        /// <param name="dtSourceId"></param>
        /// <param name="dtTableId"></param>
        /// <returns></returns>
        public ServiceResult DeleteDataTableAndMapping(string userId, Guid dtSerId, Guid dtSourceId, Guid dtTableId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.ETask> tRep = new EntityRepository<ENT.ETask>(dbContext);
                if (tRep.Count(p => p.DtSerId == dtSerId && p.DtSourceId == dtSourceId) > 0)
                {
                    return new ServiceResult(false, ErrorCode.DtSerHasTask, ErrorCode.String(ErrorCode.DtSerHasTask));
                }

                // 获取数据表和映射数据源的映射个数（多个映射关系的不能被删除数据表)
                EntityRepository<Entities.EDtSourceMapping> tsmRep = new EntityRepository<ENT.EDtSourceMapping>(dbContext);
                if(tsmRep.Count(p=>p.DtTableId == dtTableId) > 1)
                {
                    return new ServiceResult(false, ErrorCode.DtTable_HasMultipleMapping, ErrorCode.String(ErrorCode.DtTable_HasMultipleMapping));
                }

                try
                {
                    dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceMapping where DtSerId={0} and DtSourceId={1} and DtTableId={2}", dtSerId, dtSourceId, dtTableId);
                    dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceColumnMapping where DtSerId={0} and DtSourceId={1} and DtTableId={2}", dtSerId, dtSourceId, dtTableId);
                    dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceDataIdentity where DtSerId={0} and DtSourceId={1}", dtSerId, dtSourceId);

                    new LogService().Write(DEF.LogLevel.Info, "ETL", string.Format("用户:{0}删除了数据表:{1}及其和数据源:{2}的映射关系.", userId, dtTableId, dtSourceId));

                    EntityRepository<Entities.EDtTable> dtRep = new EntityRepository<ENT.EDtTable>(dbContext);
                    Entities.EDtTable eDtTable = dtRep.Get(p => p.Id == dtTableId);
                    if (eDtTable != null)
                    {
                        
                        // 删除数据表
                        new DeleteService().DeleteTable(dbContext, eDtTable);
                    }

                    return new ServiceResult();
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag(Library.LogTAG, string.Format("delete Table Mapping for dtser:{0}, dtsource:{1}, dttable:{2}, ex:{3}",
                        dtSerId,
                        dtSourceId,
                        dtTableId,
                        ex));
                    return new ServiceResult(false, ErrorCode.COM_Exception, ErrorCode.String(ErrorCode.COM_Exception));
                }
            }
        }

        /// <summary>
        /// 删除数据源对应的表，内部使用
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="userId"></param>
        /// <param name="dtSerId"></param>
        /// <param name="dtSourceId"></param>
        /// <param name="dtTableId"></param>
        /// <returns></returns>
        internal ServiceResult DeleteDataTableAndMapping(EtlDbContext dbContext, string userId, Guid dtSerId, Guid dtSourceId, Guid dtTableId)
        {
            EntityRepository<Entities.ETask> tRep = new EntityRepository<ENT.ETask>(dbContext);
            if (tRep.Count(p => p.DtSerId == dtSerId && p.DtSourceId == dtSourceId) > 0)
            {
                return new ServiceResult(false, ErrorCode.DtSerHasTask, ErrorCode.String(ErrorCode.DtSerHasTask));
            }

            // 获取数据表和映射数据源的映射个数（多个映射关系的不能被删除数据表)
            EntityRepository<Entities.EDtSourceMapping> tsmRep = new EntityRepository<ENT.EDtSourceMapping>(dbContext);
            if (tsmRep.Count(p => p.DtTableId == dtTableId) > 1)
            {
                return new ServiceResult(false, ErrorCode.DtTable_HasMultipleMapping, ErrorCode.String(ErrorCode.DtTable_HasMultipleMapping));
            }

            try
            {
                dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceMapping where DtSerId={0} and DtSourceId={1} and DtTableId={2}", dtSerId, dtSourceId, dtTableId);
                dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceColumnMapping where DtSerId={0} and DtSourceId={1} and DtTableId={2}", dtSerId, dtSourceId, dtTableId);
                dbContext.Database.ExecuteSqlCommand("delete ETL_DtSourceDataIdentity where DtSerId={0} and DtSourceId={1}", dtSerId, dtSourceId);

                new LogService().Write(DEF.LogLevel.Info, "ETL", string.Format("用户:{0}删除了数据表:{1}及其和数据源:{2}的映射关系.", userId, dtTableId, dtSourceId));

                EntityRepository<Entities.EDtTable> dtRep = new EntityRepository<ENT.EDtTable>(dbContext);
                Entities.EDtTable eDtTable = dtRep.Get(p => p.Id == dtTableId);
                if (eDtTable != null)
                {
                    // 删除数据表
                    new DeleteService().DeleteTable(dbContext, eDtTable);
                }

                return new ServiceResult();
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag(Library.LogTAG, string.Format("delete Table Mapping for dtser:{0}, dtsource:{1}, dttable:{2}, ex:{3}",
                    dtSerId,
                    dtSourceId,
                    dtTableId,
                    ex));
                return new ServiceResult(false, ErrorCode.COM_Exception, ErrorCode.String(ErrorCode.COM_Exception));
            }
        }


        public ServiceResult DeleteMaintainer(string userId, Guid id)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                Entities.Maintainer maintainer = dbContext.Set<Entities.Maintainer>().SingleOrDefault(p => p.Id == id);
                if (maintainer == null)
                {
                    return new ServiceResult(false, ErrorCode.COM_OBJNotExist, ErrorCode.String(ErrorCode.COM_OBJNotExist));
                }

                new LogService().Write(DEF.LogLevel.Info, "ETL", string.Format("用户:{0}删除监控维护员:{1}", userId, maintainer.Name));

                dbContext.Entry<Entities.Maintainer>(maintainer).State = System.Data.Entity.EntityState.Deleted;
                try
                {
                    dbContext.SaveChanges();
                    return new ServiceResult();
                }
                catch(Exception ex)
                {
                    Logger.ErrorToTag(Library.LogTAG, string.Format("删除监控维护人员:{0}出错,ex:{1}", id, ex));
                    return new ServiceResult(false, ErrorCode.COM_DBError, ex.Message);
                }
            }
        }

        public ServiceResult DeleteIntegrityCheckInstance(string userId, Guid instanceId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                try
                {
                    dbContext.Database.ExecuteSqlCommand("delete ETL_IntegrityCheckInstance where Id={0}", instanceId);
                    dbContext.Database.ExecuteSqlCommand("delete ETL_IntegrityCheckParameter where instanceId={0}", instanceId);

                    return new ServiceResult();
                }
                catch (Exception ex)
                {
                    return new ServiceResult(false, ErrorCode.COM_DBError, ex.Message);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="assemblyId"></param>
        /// <returns></returns>
        public ServiceResult DeleteExtDSAssembly(Guid assemblyId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                try
                {
                    Entities.EExtDSAssembly extDSAssembly = dbContext.Set<Entities.EExtDSAssembly>().Where(p => p.Id == assemblyId).SingleOrDefault();
                    // 检查程序集是否被使用
                    if(dbContext.Set<Entities.DtSer>().Count(p=>p.Address.Contains(extDSAssembly.Assembly)) >0)
                    {
                        return new ServiceResult(false, ErrorCode.EXTDS_Error, "扩展数据服务插件已关联了数据服务,无法删除!");
                    }
                    dbContext.Entry<Entities.EExtDSAssembly>(extDSAssembly).State = System.Data.Entity.EntityState.Deleted;
                    try
                    {
                        dbContext.SaveChanges();
                        // 删除文件
                        string assemblyFolder = string.Format("{0}ExtDS\\", System.Configuration.ConfigurationManager.AppSettings["AssemblyFolder"]);
                        string filePath = string.Format("{0}{1}.dll", assemblyFolder, extDSAssembly.Assembly);
                        System.IO.File.Delete(filePath);

                        return new ServiceResult();
                    }
                    catch(Exception ex)
                    {
                        return new ServiceResult(false, ErrorCode.COM_DBError, ex.Message);
                    }
                }
                catch (Exception ex)
                {
                    return new ServiceResult(false, ErrorCode.COM_DBError, ex.Message);
                }
            }
        }

        public ServiceResult DeleteTaskCategory(Guid categoryId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                //System.Data.Entity.DbContextTransaction transaction = dbContext.Database.BeginTransaction();
                //dbContext.Database.UseTransaction(transaction.db);
                //EtlDbContext.Remove<Entities.ETaskCategory>(dbContext.Set<Entities.ETaskCategory>(), p => p.Id == categoryId);
                dbContext.Set<Entities.ETaskCategory>().Remove(p => p.Id == categoryId);
                try
                {

                    Entities.ETaskCategory category = dbContext.Set<Entities.ETaskCategory>().SingleOrDefault(p => p.Id == categoryId);
                    if (category != null)
                    {
                        dbContext.Entry<Entities.ETaskCategory>(category).State = System.Data.Entity.EntityState.Deleted;
                        dbContext.SaveChanges();
                    }
                    return new ServiceResult();
                }
                catch (Exception ex)
                {
                    return new ServiceResult(false, ErrorCode.COM_DBError, ex.Message);
                }
            }

            return new ServiceResult();
        }
    }
}
